package tool

import (
	"fmt"
	"reflect"
	"strconv"
	"strings"
)

//最大值
func Max(vals []uint) uint {
	if len(vals) <= 0 {
		return 0
	}
	maxVal := vals[0]
	for _, val := range vals {
		if maxVal < val {
			maxVal = val
		}
	}
	return maxVal
}

//去重int
func RemoveDuplicationInt(arr []int) []int {
	set := make(map[int]struct{}, len(arr))
	j := 0
	for _, v := range arr {
		_, ok := set[v]
		if ok {
			continue
		}
		set[v] = struct{}{}
		arr[j] = v
		j++
	}

	return arr[:j]
}
func ToString(v interface{}) string {
	return fmt.Sprintf("%v", v)
}

func SliceToStringSlice(v interface{}) (ret []string, err error) {
	reflectVal := reflect.ValueOf(v)
	if reflectVal.Type().Kind().String() != "slice" {
		return ret, fmt.Errorf("SliceToStringSlice() input value is not a slice ")
	}
	length := reflectVal.Len()
	ret = make([]string, 0, length)
	for i := 0; i < length; i++ {
		rval := reflectVal.Index(i)
		ret = append(ret, ToString(rval.Interface()))
	}
	return ret, nil
}

//去重int64
func RemoveDuplicationInt64(arr []int64) []int64 {
	set := make(map[int64]struct{}, len(arr))
	j := 0
	for _, v := range arr {
		_, ok := set[v]
		if ok {
			continue
		}
		set[v] = struct{}{}
		arr[j] = v
		j++
	}

	return arr[:j]
}

//快排(先获取基数，然后比较 把左边的递归比较 然后后边的递归比较 最后合并)
func QuickSort(arr []uint64) []uint64 {
	if len(arr) <= 1 {
		return arr
	}
	splitdata := arr[0]           //第一个数据
	low := make([]uint64, 0, 0)   //比我小的数据
	hight := make([]uint64, 0, 0) //比我大的数据
	mid := make([]uint64, 0, 0)   //与我一样大的数据
	mid = append(mid, splitdata)  //加入第一个
	for i := 1; i < len(arr); i++ {
		if arr[i] < splitdata {
			low = append(low, arr[i]) //比我小的数据
		} else if arr[i] > splitdata {
			hight = append(hight, arr[i]) //比我大的数据
		} else {
			mid = append(mid, arr[i])
		}
	}
	low, hight = QuickSort(low), QuickSort(hight)
	myArr := append(append(low, mid...), hight...)
	return myArr
}

//去重Uint64
func RemoveDuplicationUInt64(arr []uint64) []uint64 {
	set := make(map[uint64]struct{}, len(arr))
	j := 0
	for _, v := range arr {
		_, ok := set[v]
		if ok {
			continue
		}
		set[v] = struct{}{}
		arr[j] = v
		j++
	}

	return arr[:j]
}

// 判断某一个值是否含在切片之中
//@param need 需要判断的值
//@param haystack 对比数组
func InArray(need interface{}, haystack interface{}) bool {
	switch key := need.(type) {
	case int:
		for _, item := range haystack.([]int) {
			if item == key {
				return true
			}
		}
	case string:
		for _, item := range haystack.([]string) {
			if item == key {
				return true
			}
		}
	case int64:
		for _, item := range haystack.([]int64) {
			if item == key {
				return true
			}
		}
	case uint64:
		for _, item := range haystack.([]uint64) {
			if item == key {
				return true
			}
		}
	case float64:
		for _, item := range haystack.([]float64) {
			if item == key {
				return true
			}
		}
	default:
		return false
	}
	return false
}

// 判断某一个值是否含在切片之中
//@param need 需要判断的值
//@param haystack 对比数组
func SearchArray(need int, haystack []int) int {
	for k, item := range haystack {
		if item == need {
			return k
		}
	}

	return -1
}

// 判断某一个值是否含在切片之中
//@param need 需要判断的值
//@param haystack 对比数组
func SearchUint64Array(need uint64, haystack []uint64) int {
	for k, item := range haystack {
		if item == need {
			return k
		}
	}

	return -1
}

//切分为Uint64
func SplitToUInt64List(str string, sep string) (i64List []uint64) {
	if str == "" {
		return
	}
	strList := strings.Split(str, sep)
	if len(strList) == 0 {
		return
	}
	for _, item := range strList {
		if item == "" {
			continue
		}
		val, err := strconv.ParseUint(item, 10, 64)
		if err != nil {
			// logs.CtxError(ctx, "ParseInt fail, err=%v, str=%v, sep=%v", err, str, sep) // 此处打印出log报错信息
			continue
		}
		i64List = append(i64List, val)
	}
	return i64List
}

//切分为int64
func SplitToInt64List(str string, sep string) (i64List []int64) {
	if str == "" {
		return
	}
	strList := strings.Split(str, sep)
	if len(strList) == 0 {
		return
	}
	for _, item := range strList {
		if item == "" {
			continue
		}
		val, err := strconv.ParseInt(item, 10, 64)
		if err != nil {
			// logs.CtxError(ctx, "ParseInt fail, err=%v, str=%v, sep=%v", err, str, sep) // 此处打印出log报错信息
			continue
		}
		i64List = append(i64List, val)
	}
	return i64List
}

//切分为int
func SplitToInList(str string, sep string) (iList []int) {
	if str == "" {
		return
	}
	strList := strings.Split(str, sep)
	if len(strList) == 0 {
		return
	}
	for _, item := range strList {
		if item == "" {
			continue
		}
		val, err := strconv.Atoi(item)
		if err != nil {
			// logs.CtxError(ctx, "ParseInt fail, err=%v, str=%v, sep=%v", err, str, sep) // 此处打印出log报错信息
			continue
		}
		iList = append(iList, val)
	}
	return iList
}

func SplitToString(data []uint64, sep string) string {
	return strings.Replace(strings.Trim(fmt.Sprint(data), "[]"), " ", sep, -1)
}

func SplitToStringList(str string, sep string) (i64List []string) {
	if str == "" {
		return
	}
	strList := strings.Split(str, sep)
	if len(strList) == 0 {
		return
	}
	for _, item := range strList {
		if item == "" {
			continue
		}

		i64List = append(i64List, item)
	}
	return i64List
}

func SplitToUIntList(str string, sep string) (i64List []uint) {
	if str == "" {
		return
	}
	strList := strings.Split(str, sep)
	if len(strList) == 0 {
		return
	}
	for _, item := range strList {
		if item == "" {
			continue
		}
		itemInt, err := strconv.Atoi(item)
		if err != nil {
			// logs.CtxError(ctx, "ParseInt fail, err=%v, str=%v, sep=%v", err, str, sep) // 此处打印出log报错信息
			continue
		}
		val := uint(itemInt)

		i64List = append(i64List, val)
	}
	return i64List
}

//数组[]uint64比较值返回交集值
func ArrayIntersect(arrA []uint64, arrayB []uint64) []uint64 {
	resArr := make([]uint64, 0)
	m := make(map[uint64]bool)
	for _, v := range arrA {
		m[v] = true
	}
	for _, vb := range arrayB {
		if val, _ := m[vb]; val == true {
			resArr = append(resArr, vb)
		}
	}
	return resArr
}

//比较两个数组是否相等
func Uint64SliceEqual(a, b []uint64) bool {
	if len(a) != len(b) {
		return false
	}

	if (a == nil) != (b == nil) {
		return false
	}
	for i, v := range a {
		if v != b[i] {
			return false
		}
	}

	return true
}

//数组前面添加一个固定的值
func AddArrHeaderText(Arr []string, text string) []string {
	if len(Arr) == 0 {
		return []string{}
	}
	for k, v := range Arr {
		Arr[k] = text + "." + v
	}

	return Arr
}

//差集[]string
func SliceStringDiff(arr1 []string, arrs ...[]string) (data []string) {
	if len(arrs) == 0 {
		return arr1
	}
	i := 0
loop:
	for {
		if i == len(arr1) {
			break
		}
		v := arr1[i]
		for _, arr := range arrs {
			for _, val := range arr {
				if v == val {
					i++
					continue loop
				}
			}
		}
		data = append(data, v)
		i++
	}
	return

}

//差集[]uint64
func SliceUint64Diff(arr1 []uint64, arrs ...[]uint64) (data []uint64) {
	if len(arrs) == 0 {
		return arr1
	}
	i := 0
loop:
	for {
		if i == len(arr1) {
			break
		}
		v := arr1[i]
		for _, arr := range arrs {
			for _, val := range arr {
				if v == val {
					i++
					continue loop
				}
			}
		}
		data = append(data, v)
		i++
	}
	return

}

//删除数组Map字段
func DeleteSinceMap(data []map[string]interface{}, index int) []map[string]interface{} {
	if len(data) == 0 {
		return data
	}
	data = append(data[:index], data[index+1:]...)
	return data
}

//删除切片
func DeleteUint64Since(data []uint64, index int) []uint64 {
	if len(data) == 0 {
		return data
	}
	data = append(data[:index], data[index+1:]...)
	return data
}

//删除切片
func DeleteIntSince(data []int, index int) []int {
	if len(data) == 0 {
		return data
	}
	data = append(data[:index], data[index+1:]...)
	return data
}

//[]uint64 转换成[]int
func SinceUint64TransInt(data []uint64) []int {
	if len(data) == 0 {
		return []int{}
	}
	var resData []int
	for _, i2 := range data {
		val, _ := strconv.Atoi(strconv.FormatUint(i2, 10))
		resData = append(resData, val)
	}
	return resData
}
